/**
 * @addtogroup gbc_msg_17691
 * gbc_17691_msg
 * @brief        国六消息基类
 * @par 示例
 * @code
   // 国六消息的编解码功能，子类可以实现具体的编解码事件来完成特定消息的编解码

   // 作为其他消息的基类使用，如下定义一个登入消息
   typedef struct TGbc17691MsgLoginTag TGbc17691MsgLogin;
   struct TGbc17691MsgLoginTag
   {
   PROTECTED
       TGbc17691Msg parent_;                ///< 基类
       TOfVirtualMethod Destroy_;          ///< 析构事件

   PUBLIC
       UInt8 collect_time[6];              ///< 数据采集时间
       UInt16 login_seq;                   ///< 登入流水号，从1开始, 循环累加，最大65531,以天为单位
       Int8 iccid[32];                     ///< SIM卡的ICCID号码
   };

   // 实现文件
   // 编码实现接口
   static Int32 TGbc17691MsgLoginEncode(TGbc17691MsgLogin *self, TGbc17691Mgr *msg_mgr, Byte *buf, Int32 buf_size)
   {
       ...
   }

   // 解码实现接口
   static Bool TGbc17691MsgLoginDecode(TGbc17691MsgLogin *self, TGbc17691Mgr *msg_mgr, Byte *buf, Int32 buf_size)
   {
       ...
   }

   // 析构函数
   static void TGbc17691MsgLoginDestroy(TOfObject *sender)
   {
      ...
   }

   // 在子类中实现创建对象
   void TGbc17691MsgLoginCreate(TGbc17691MsgLogin *self)
   {
       TGbc17691MsgCreate((TGbc17691Msg *)self, kGbc17691CmdLogin);
       OVERRIDE_METHOD(TOfObject, Destroy, TGbc17691MsgLoginDestroy);
       self->parent_.DoEncode = (TGbc17691MsgDoEncodeEvent)TGbc17691MsgLoginEncode;
       self->parent_.DoDecode = (TGbc17691MsgDoDecodeEvent)TGbc17691MsgLoginDecode;
   }
 * @endcode
 * @{
 */
/**
 * @file         gbc_17691_msg.h
 * @brief        国六消息基类
 * @note
 * @author       Dengdeshou
 * @date         2020-08-07
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-08-07  <td>1.0                   <td>Dengdeshou      <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _SCC_PT17691_MSG_H_
#define _SCC_PT17691_MSG_H_

#include "ofc/ofc_object.h"
#include "gbmsg17691/gbc_17691_mgr.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct TGbc17691MsgTag TGbc17691Msg;

/**
 * 国六命令字定义
 */
typedef enum TGbc17691CmdEnumTag TGbc17691CmdEnum;
enum TGbc17691CmdEnumTag
{
    kGbc17691CmdLogin = 0x01,       ///< 登入
    kGbc17691CmdReal = 0x02,        ///< 实时信息流上报
    kGbc17691CmdReissue = 0x03,     ///< 补发信息上报
    kGbc17691CmdLogout = 0x04,      ///< 登出
    kGbc17691CmdCheckTime = 0x05,   ///< 校时
    kGbc17691CmdZzStreamAck = 0xf0, ///< 郑州系协议信息流应答包
};

/**
 * 编码事件
 * @param sender: 对象指针
 * @param encode_buf: 编码后存放的数据缓冲
 * @param encode_buf_size: 编码存放的数据大小
 * @return >=0: 编码成功,编码后的字节数; <0: 编码失败
 */
typedef Int32(*TGbc17691MsgDoEncodeEvent)(TGbc17691Msg *self, TGbc17691Mgr *msg_mgr, Byte *encode_buf, Int32 encode_buf_size);

/**
 * 解码事件
 * @param sender: 对象指针
 * @param decode_buf: 需要解码的数据缓冲,不包含头0x23,包含消息和校验码
 * @param decode_buf_size: 需要解码的数据大小
 * @return True: 解码成功; False: 解码失败
 */
typedef Bool(*TGbc17691MsgDoDecodeEvent)(TGbc17691Msg *self, TGbc17691Mgr *msg_mgr, Byte *decode_buf, Int32 decode_buf_size);

/**
 * 国六协议消息基类
 */
struct TGbc17691MsgTag
{
PROTECTED
    TOfObject parent_;          ///< 基类
    TOfVirtualMethod Destroy_;  ///< 析构事件

PUBLIC
    TGbc17691MsgDoEncodeEvent DoEncode;   ///< 编码事件
    TGbc17691MsgDoDecodeEvent DoDecode;   ///< 解码事件

PROTECTED
    UInt8 cmd_;               ///< 命令单元
};

/**
 * 交通部消息808基类构造函数
 * @param self: 对象指针
 * @return
 */
void TGbc17691MsgCreate(TGbc17691Msg *self, UInt8 cmd);

/**
 * 编码函数
 * @param self: 对象指针
 * @param msg_mgr: 消息管理器
 * @param buf: 编码后的数据内存存放地址
 * @param buf_size: 编码的数据存放大小
 * @return >0: 编码成功,编码后的大小; <=0: 编码失败
 */
Int32 TGbc17691MsgEncode(TGbc17691Msg *self, TGbc17691Mgr *msg_mgr, Byte *buf, Int32 buf_size);

/**
* 解码函数
* @param self: 对象指针
* @param msg_mgr: 消息管理器
* @param buf: 需要解码的数据缓冲, 不包含头0x23,包含消息和校验码
* @param buf_size: 需要解码的数据大小
* @return True: 解码成功; False: 解码失败
*/
Bool TGbc17691MsgDecode(TGbc17691Msg *self, TGbc17691Mgr *msg_mgr, Byte *buf, Int32 buf_size);

/**
 * 获取命令字
 * @param self: 对象指针
 * @return 命令字
 */
UInt8 TGbc17691MsgCmdId(TGbc17691Msg *self);

/**
 * 设置命令字
 * @param self: 对象指针
 * @param cmd: 命令字
 * @return
 */
//void TGbc17691MsgSetCmdId(TGbc17691Msg *self, UInt8 cmd);

#ifdef __cplusplus
}
#endif

#endif

/**
 * @} 
 */
